from PyQt4.QtGui import QPushButton
from phonik.plugin import UIPlugin
from phonik.plugin import Plugin
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import QFont
from PyQt4.QtCore import SLOT
from PyQt4.QtCore import QObject
from PyQt4.QtGui import QSplitter
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QAbstractItemView
from PyQt4 import QtGui
from PyQt4.QtGui import QColumnView
from PyQt4.QtGui import QTableView
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtCore import QSize
from PyQt4.QtGui import QDirModel, QCursor
from PyQt4.QtCore import QDir, QStringList
from PyQt4.QtCore import Qt, QString, QMimeData, QVariant, QAbstractTableModel, QModelIndex
from PyQt4.QtGui import qApp, QMenu, QAction, QFileDialog, QDesktopServices, QApplication, QStringListModel, QInputDialog, QLineEdit, QHeaderView, QDialog, QLabel
from PyQt4 import QtCore

import os, sys


class Radio(UIPlugin):
    def load(self):

        #set plugin name
        self.setName('Radio')

        # create widgets
        self.view = QTableView(self.mw)
        self.view.setShowGrid(False)
        self.view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.view.customContextMenuRequested.connect(self.showContextMenu)
        self.view.setEditTriggers(QAbstractItemView.AllEditTriggers)
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.view.setSelectionMode(QAbstractItemView.ExtendedSelection)

        # set model
        self.model = RadioModel()
        self.view.setModel(self.model)

        # first run
        if self.firstRun():
            self.view.setColumnHidden(2, True)
            self.view.horizontalHeader().setResizeMode(0, QHeaderView.Stretch)
            self.view.horizontalHeader().setDefaultSectionSize(250)
            self.view.horizontalHeader().setFixedHeight(17)

        # restore settind
        if self.hasOption('stations'):
            self.model.setAllData(eval(self.get('stations')))
        if self.hasOption('header'):
            self.view.horizontalHeader().restoreState(self.get('header', '0'))

        # drag and drop
        self.view.setDragDropMode(QAbstractItemView.DragDrop)
        self.view.setDragEnabled(True)
        self.view.setAcceptDrops(True)


        # horizontal header
        hh = self.view.horizontalHeader()
        hh.setContextMenuPolicy(Qt.CustomContextMenu)
        hh.customContextMenuRequested.connect(self.showHeaderContextMenu)
        hh.setFont(QFont("Sans", 7))


        # vertical header
        vh = self.view.verticalHeader()
        vh.hide()
        vh.setDefaultSectionSize(21)

        # crate menu
        self.createMenu()

        # add page to the main window
        self.addPage(self.view)

        # signals
        self.view.clicked.connect(self.stationClicked)


    def unload(self):
        self.set('stations', self.model.getAllData())
        self.set('header', self.view.horizontalHeader().saveState())



    def showContextMenu(self, pos):
        actionList = [QAction(self.tr('Remove'), self.view), QAction(self.tr('Edit'), self.view)]
        result = QMenu().exec_(actionList, QCursor.pos())
        if result:
            if result.text() == self.tr('Remove'):
                for index in self.view.selectionModel().selectedRows():
                    self.view.model().removeRow(index.row())

            if result.text() == self.tr('Edit'):
                for index in self.view.selectionModel().selectedRows():
                    rowNumber = index.row()
                    name = index.data().toString()
                    genre = index.sibling(rowNumber, 1).data().toString()
                    url = index.sibling(rowNumber, 2).data().toString()
                    row = StationDialog(self.mw).edit(name, genre, url)
                    if row:
                        self.view.model().setRowData(rowNumber, row)


    def showHeaderContextMenu(self):
        menu = QMenu()

        for i in range(0, self.model.columnCount()):
            action = menu.addAction(self.model.headerData(i, Qt.Horizontal).toString())
            action.setProperty('column', QVariant(i))
            action.setCheckable(True)
            if not self.view.isColumnHidden(i):
                action.setChecked(True)

        self.connect(menu, SIGNAL('triggered (QAction *)'), self.runHeaderContextMenu)
        menu.exec_(QCursor.pos())


    def runHeaderContextMenu(self, action):
        column = int(action.property('column').toString())
        self.view.setColumnHidden(column, not self.view.isColumnHidden(column))


    def createMenu(self):
        self.menuRadio = QMenu(self.getMenuBar())
        self.menuRadio.setTitle(self.tr('Radio'))

        self.actionAddStation = QAction(self.tr('Add radio station'), self.mw)
        self.actionAddStation.triggered.connect(self.addStation)
        self.menuRadio.addAction(self.actionAddStation)

        self.getMenuBar().addAction(self.menuRadio.menuAction())


    def addStation(self):
        row = StationDialog(self.mw).show()

        if row:
            self.model.appendRow(row)


    def stationClicked(self, index):
        self.player.play(index.sibling(index.row(), 2).data().toString())


class RadioModel(QAbstractTableModel):
    def __init__(self):
        QAbstractTableModel.__init__(self)

        #the main storage
        self.table = []


    def index (self, row, column, parent):
        return  self.createIndex(row, column)


    def insertRow(self, pos, row):
        self.insertRows(pos, 1, row)


    def insertRows(self, pos, count, rows):
        self.beginInsertRows(QModelIndex(), pos, pos + count - 1)
        self.table.insert(pos, rows)
        self.endInsertRows()
        self.emit(SIGNAL('layoutChanged()'))
        return True


    def appendRow(self, row):
        self.insertRows(len(self.table), 1, row)


    def removeRow(self, pos):
        self.removeRows(pos, 1)
        return True

    def removeRows(self, row=-1, count=0, parent=QModelIndex()):
        if row == -1:
            self.beginRemoveRows(QModelIndex(), 0, len(self.table) - 1)
            del self.table[:]
        else:
            self.beginRemoveRows(QModelIndex(), row, row + count - 1)
            del self.table[row:row + count]
        self.endRemoveRows()
        self.emit(SIGNAL('layoutChanged()'))
        return True


    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            if section == 0:
                return QVariant('Station name')
            if section == 1:
                return QVariant(self.tr('Genre'))
            if section == 2:
                return QVariant(self.tr('URL'))

        return QVariant()


    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return QVariant()

        if role != Qt.DisplayRole:
            return QVariant()

        if len(self.table) > index.row():
            return QVariant(self.table[index.row()][index.column()])
        return QVariant()


    def setData(self, index, value):
        self.table[index.row()][index.column()] = value
        return True

    def setRowData(self, rowNumber, data):
        self.table[rowNumber] = data


    def getAllData(self):
        return self.table


    def setAllData(self, table):
        self.table = table


    def rowCount(self, parent=QModelIndex()):
        return len(self.table)


    def columnCount(self, parent=QModelIndex()):
        return 3


class StationDialog(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent)

        self.resize(400, 200)

        # widgets
        vl = QVBoxLayout(self)

        name = QLabel(self.tr('Name') + ':')
        vl.addWidget(name)

        self.nameEdit = QLineEdit(self.tr('Station'))
        vl.addWidget(self.nameEdit)

        genre = QLabel(self.tr('Genre') + ':')
        vl.addWidget(genre)

        self.genreEdit = QLineEdit()
        vl.addWidget(self.genreEdit)

        url = QLabel(self.tr('URL') + ':')
        vl.addWidget(url)

        self.urlEdit = QLineEdit('http://')
        vl.addWidget(self.urlEdit)

        buttonsWidget = QWidget(self)
        hl = QHBoxLayout(buttonsWidget)
        hl.setMargin(0)
        hl.setSpacing(0)
        hl.addSpacing(150)

        cancelButton = QPushButton(self.tr('Cancel'))
        cancelButton.pressed.connect(self.reject)
        hl.addWidget(cancelButton)

        okButton = QPushButton(self.tr('OK'))
        okButton.pressed.connect(self.accept)
        hl.addWidget(okButton)

        vl.addWidget(buttonsWidget)

    def edit(self, name, genre, url):
        self.nameEdit.setText(name)
        self.genreEdit.setText(genre)
        self.urlEdit.setText(url)
        return self.show()


    def show(self):
        l = []
        if self.exec_():
            l.append(unicode(self.nameEdit.text().toUtf8(), 'utf-8'))
            l.append(unicode(self.genreEdit.text().toUtf8(), 'utf-8'))
            l.append(unicode(self.urlEdit.text().toUtf8(), 'utf-8'))
            return l
        else:
            return None